<?php

namespace App\Console\Commands;

use App\Models\Agent;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;

class RemoveHistoryPerformance extends Command
{
    /**
     * 命令名称及签名
     *
     * @var string
     */
    protected $signature = 'migrate:remove_history_performance';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '剔除历史系统业绩';

    /**
     * 代理商总数
     * @var int
     */
    protected $agentCount = 0;

    public function handle()
    {
        try {
            $this->agentCount = Agent::query()->count();
            $bar = $this->output->createProgressBar($this->agentCount);
            $bar->start();
            Agent::query()
                ->withTrashed()
                ->select(['id'])
                ->chunk(5000, function (Collection $agents) use ($bar) {
                    $agents->each(function (Agent $agent) use ($bar) {
                        // 是否已经完成过了 (第一道判断, 省去去获取锁的消耗)
                        if (0 !== Redis::hexists('migrate:agent_remove_performance', $agent['id'])) {
                            return false;
                        }

                        Cache::lock('migrate:agent_' . $agent['id'] . '_remove_performance_lock', 1 * 60 * 60)
                            ->get(function () use ($agent) {
                                // 是否已经完成过了 (第二道判断, 防止有进程通过了第一道, 然后此时释放锁, 就会再一次获取锁并进入处理)
                                if (0 !== Redis::hexists('migrate:agent_remove_performance', $agent['id'])) {
                                    return false;
                                }

                                // 旧系统值
                                $agentPerformance = (int) (Redis::hget('migrate:agent_performance', $agent['id']) ?? 0);
                                $agentTeamPerformance = (int) (Redis::hget('migrate:agent_team_performance', $agent['id']) ?? 0);
                                if ($agentPerformance > 0 || $agentTeamPerformance > 0) {
                                    try {
                                        \DB::beginTransaction();

                                        $agentPerformance > 0 && $agent->decrement('personal_performance', $agentPerformance);
                                        $agentTeamPerformance > 0 && $agent->decrement('team_performance', $agentTeamPerformance);

                                        \DB::commit();
                                    } catch (\Exception $e) {
                                        \DB::rollBack();

                                        Redis::hset('migrate:agent_remove_performance_error', $agent['id'], $e->getMessage());
                                        return false;
                                    }
                                }

                                // 已完成
                                Redis::hset('migrate:agent_remove_performance', $agent['id'], json_encode([
                                    'personal_performance' => $agentPerformance,
                                    'team_performance' => $agentTeamPerformance
                                ]));
                                return true;
                            });

                        $bar->advance(1);
                        return true;
                    });
                });
            $bar->finish();
        } catch (\Exception $e) {
            $this->output->error($e->getMessage());
        }
    }
}
